package dao

import (
	"errors"
	"gitee.com/gopher2011/mbt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
	"log"
	"os"
	"time"
)

type Page struct {
	PageNum  int `json:"page_num" form:"page_num"`
	PageSize int `json:"page_size" form:"page_size"`
}

const (
	MaxOpenConn = 10
	MaxIdleConn = 5
	DSN         = "root:root@tcp(127.0.0.1:3306)/godemo?charset=utf8mb4&parseTime=True&loc=Local"
	DriverName  = "mysql"
)

var (
	DB *sqlx.DB
	Log *log.Logger
)

func init() {
	cfg := &mbt.Config{
		DriverName:  DriverName,
		DSN:         DSN,
		MaxIdleConn: MaxIdleConn,
		MaxOpenConn: MaxOpenConn,
		Pkg:         "./server/dao",
		PrintSql:    true,
	}
	engine, db, err := mbt.New(cfg)
	if err != nil {
		panic(err)
	}
	conn := sqlx.NewDb(db, "mysql")
	DB = conn
	h := Init()
	engine.Register(h)
	//engine.Run()
}

func init(){
	// 获取日志文件句柄
	logFile,err := os.OpenFile(`./server.log`,os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		panic(err)
	}
	// 设置日志输出位置
	log.SetOutput(logFile)
}
func Init() map[interface{}]interface{} {
	h := mbt.H{
		&AdvertisementDao:      &Advertisement{},      // 广告表
		&ArticleDao:            &Article{},            // 网络文章聚合表
		&ArticleGcttDao:        &ArticleGctt{},        // gctt 翻译文章信息表
		&AuthorityDao:          &Authority{},          // 权限表，常驻内存
		&BindUserDao:           &BindUser{},           // 第三方绑定表
		&BookDao:               &Book{},               // 图书表
		&CommentDao:            &Comment{},            // 评论表(帖子回复、博客文章评论等，统一处理)
		&DefaultAvatarDao:      &DefaultAvatar{},      // 默认头像
		&DownloadDao:           &Download{},           // 下载信息表
		&DynamicDao:            &Dynamic{},            // 动态表
		&FavoriteDao:           &Favorite{},           // 用户收藏
		&FeedDao:               &Feed{},               // 网站关键资源动态表
		&FriendLinkDao:         &FriendLink{},         // 友情链接
		&GcttGitDao:            &GcttGit{},            // Go语言中文网翻译组 github 文章翻译信息表
		&GcttIssueDao:          &GcttIssue{},          // GCTT github 选题 issue 列表
		&GcttTimelineDao:       &GcttTimeline{},       // GCTT 大事记
		&GcttUserDao:           &GcttUser{},           // Go语言中文网翻译组用户表
		&GiftDao:               &Gift{},               // 物品表
		&GiftCodeDao:           &GiftCode{},           // 物品兑换码
		&ImageDao:              &Image{},              // 图片表
		&LearningMaterialDao:   &LearningMaterial{},   // 成体系的学习资料
		&LikeDao:               &Like{},               // 喜欢表
		&MessageDao:            &Message{},            // message 短消息(私信)
		&MissionDao:            &Mission{},            // 任务表
		&MorningReadingDao:     &MorningReading{},     // 技术晨读表
		&OpenProjectDao:        &OpenProject{},        // 开源项目
		&RecommendNodeDao:      &RecommendNode{},      // 导航推荐节点
		&ResourceDao:           &Resource{},           // 资源
		&RoleDao:               &Role{},               // 角色表，常驻内存
		&SearchTermsDao:        &SearchTerms{},        // 搜索词统计
		&SubjectDao:            &Subject{},            // 专栏
		&SubjectAdminDao:       &SubjectAdmin{},       // 专栏管理员(不包括创建者)
		&SubjectArticleDao:     &SubjectArticle{},     // 专栏文章列表
		&SubjectFollowerDao:    &SubjectFollower{},    // 专栏关注者
		&TopicDao:              &Topic{},              // 主题内容表
		&TopicAppendDao:        &TopicAppend{},        // 主题附言表
		&TopicExDao:            &TopicEx{},            // 主题扩展表(计数)
		&TopicNodeDao:          &TopicNode{},          // 帖子节点表
		&UserDao:               &User{},               // 用户信息表
		&UserActiveDao:         &UserActive{},         // 活跃用户表
		&UserBalanceDetailDao:  &UserBalanceDetail{},  // 用户余额明细
		&UserExchangeRecordDao: &UserExchangeRecord{}, // 用户物品兑换记录
		&UserLoginDao:          &UserLogin{},          // 用户登陆表
		&UserLoginMissionDao:   &UserLoginMission{},   // 用户登陆任务
		&UserRechargeDao:       &UserRecharge{},       // 用户充值记录表
		&UserRoleDao:           &UserRole{},           // 用户角色表(用户是什么角色,可以多个角色)
		&UserSettingDao:        &UserSetting{},        // 用户设置
		&ViewRecordDao:         &ViewRecord{},         // 用户浏览记录表
		&ViewSourceDao:         &ViewSource{},         // 浏览来源表
		&WebsiteSettingDao:     &WebsiteSetting{},     // 网站设置信息
		&WechatAutoReplyDao:    &WechatAutoReply{},    // 微信自动回复
		&WechatUserDao:         &WechatUser{},         // 微信用户绑定表
	}
	return h
}

// go 中类型转换: https://www.bilibili.com/video/BV18h411C7Yz?from=search&seid=5307420270388852885
type LocalTime time.Time // LocalTime是建立在 time.Time之上的新类型

func NewLocalTime()LocalTime{
	t ,_ := time.ParseInLocation("2006-01-02 15:04:05", "2000-01-01 00:00:00", time.Local)
	return LocalTime(t)
}

func (it LocalTime)MarshalJSON()([]byte,error){
	t := time.Time(it) // 将 LocalTime转换成 time.Time类型。
	if y := t.Year();y<0 || y >= 10000 {
		if y < 2000 {
			return []byte(`"2000-01-01 00:00:00"`),nil
		}
		return nil,errors.New(" Time.MarshalJSON: year outside of range [0,9999]")
	}
	return []byte(t.Format(`"2006-01-02 15:04:05"`)),nil
}

func (it LocalTime)MarshalText()([]byte,error){
	return time.Time(it).MarshalText()
}


func (it LocalTime)MarshalBinary()([]byte,error){
	return time.Time(it).MarshalBinary()
}

func (it *LocalTime)UnmarshalJSON(data[]byte)(err error){
	str := string(data)
	if str == "null" {
		return nil
	}
	if str == `"0001-01-01 08:00:00"` {
		ft := NewLocalTime()
		it = &ft
		return nil
	}

	var t time.Time
	t,err = time.ParseInLocation(`"2006-01-02 15:04:05"`, str, time.Local)
	*it = LocalTime(t) //将 time.Time类型转换成 LocalTime类型
	return
}

func (it *LocalTime)UnmarshalBinary(data[]byte)(err error){
	t := time.Time(*it)
	return t.UnmarshalBinary(data)
}
func (it *LocalTime)UnmarshalText(data[]byte)(err error){
	t := time.Time(*it) //显示的将 LocalTime转换成 time.Time
	return t.UnmarshalText(data)
}

func (it LocalTime)String()string{
	t := time.Time(it)
	if t.IsZero() {
		return "0000-00-00 00:00:00"
	}
	return t.Format("2006-01-02 15:04:05")
}


